using System;
using Fornax020.SerialComm.Protocol;

namespace Fornax020.SerialComm.Parsing
{
    /// <summary>
    /// X射线设备数据验证器
    /// 实现串口通信数据的格式验证
    /// </summary>
    public class DataValidator : IDataValidator
    {
        /// <summary>
        /// 验证数据格式
        /// </summary>
        /// <param name="data">要验证的数据</param>
        /// <returns>验证结果</returns>
        public ValidationResult Validate(string data)
        {
            // 检查数据是否为空
            if (string.IsNullOrEmpty(data))
            {
                return ValidationResult.Invalid("数据为空");
            }

            // 检查最小长度
            if (data.Length < 3)
            {
                return ValidationResult.Invalid($"数据长度不足，期望至少3个字符，实际{data.Length}个字符");
            }

            // 检查起始字符（如果协议要求）
            if (data[0] != ProtocolConstants.STX)
            {
                // 如果不是标准格式，检查是否为无STX格式
                if (!IsValidWithoutStx(data))
                {
                    return ValidationResult.Invalid($"无效的起始字符，期望STX(0x02)，实际0x{((int)data[0]):X2}");
                }
            }

            // 检查结束字符 - 优先支持标准CR结尾
            char lastChar = data[data.Length - 1];
            if (lastChar != ProtocolConstants.CR)
            {
                // 如果不是CR，检查是否为MO指令的空字节结尾（临时兼容）
                if (lastChar == 0x00 && data.Length >= 3)
                {
                    string commandType = data.Substring(1, 2);
                    if (commandType == ProtocolConstants.CommandTypes.MONITOR_DATA)
                    {
                        // MO指令暂时允许空字节结尾（等待下位机修正）
                        System.Diagnostics.Debug.WriteLine($"[DataValidator] MO指令使用空字节结尾（临时兼容）");
                    }
                    else
                    {
                        return ValidationResult.Invalid($"无效的结束字符，期望CR(0x0D)，实际0x{((int)lastChar):X2}");
                    }
                }
                else
                {
                    return ValidationResult.Invalid($"无效的结束字符，期望CR(0x0D)，实际0x{((int)lastChar):X2}");
                }
            }

            // 检查命令类型
            if (data.Length >= 3)
            {
                string commandType = data.Substring(1, 2);
                if (!IsValidCommandType(commandType))
                {
                    return ValidationResult.Invalid($"无效的命令类型: {commandType}");
                }
            }

            // 检查数据包长度
            if (data.Length >= 3)
            {
                string commandType = data.Substring(1, 2);
                int expectedLength = GetExpectedPacketLength(commandType);
                if (expectedLength > 0 && data.Length != expectedLength)
                {
                    return ValidationResult.Invalid($"数据包长度不匹配，期望{expectedLength}个字符，实际{data.Length}个字符");
                }
            }

            return ValidationResult.Valid();
        }

        /// <summary>
        /// 检查无STX格式是否有效
        /// </summary>
        private bool IsValidWithoutStx(string data)
        {
            // 检查是否为已知的无STX格式
            if (data.Length >= 2)
            {
                string commandType = data.Substring(0, 2);
                return IsValidCommandType(commandType);
            }
            return false;
        }

        /// <summary>
        /// 检查命令类型是否有效
        /// </summary>
        private bool IsValidCommandType(string commandType)
        {
            return commandType == ProtocolConstants.CommandTypes.KV_FEEDBACK ||
                   commandType == ProtocolConstants.CommandTypes.MA_FEEDBACK ||
                   commandType == ProtocolConstants.CommandTypes.FIL_FEEDBACK ||
                   commandType == ProtocolConstants.CommandTypes.MONITOR_DATA ||
                   commandType == ProtocolConstants.CommandTypes.FIRMWARE_VERSION ||
                   commandType == ProtocolConstants.CommandTypes.ERROR_INFO;
        }

        /// <summary>
        /// 获取期望的数据包长度
        /// </summary>
        private int GetExpectedPacketLength(string commandType)
        {
            switch (commandType)
            {
                case ProtocolConstants.CommandTypes.KV_FEEDBACK:
                    return ProtocolConstants.PacketLength.KV_FEEDBACK;
                case ProtocolConstants.CommandTypes.MA_FEEDBACK:
                    return ProtocolConstants.PacketLength.MA_FEEDBACK;
                case ProtocolConstants.CommandTypes.FIL_FEEDBACK:
                    return ProtocolConstants.PacketLength.FIL_FEEDBACK;
                case ProtocolConstants.CommandTypes.MONITOR_DATA:
                    return ProtocolConstants.PacketLength.MONITOR_DATA;
                case ProtocolConstants.CommandTypes.FIRMWARE_VERSION:
                    return ProtocolConstants.PacketLength.FIRMWARE_VERSION;
                case ProtocolConstants.CommandTypes.ERROR_INFO:
                    return ProtocolConstants.PacketLength.ERROR_INFO;
                default:
                    return 0; // 未知命令类型，不检查长度
            }
        }
    }
}
